﻿(function(exports) {
	$(document).ready(function() {

		/*
		 * Define sound module
		 *
		 */
		var AvifaunaSound = (function() {

			var audioContext,
				analyser,
				gainNode;
			
			function init() {
				audioContext = new window.webkitAudioContext();
				analyser = audioContext.createAnalyser();
				gainNode = audioContext.createGainNode();
				changeVolume(AvifaunaConfig.defaultVolume);
			};
			
			function changeVolume(volume) {
				var fraction = parseInt(volume) / 100;
				gainNode.gain.value = fraction * fraction;
				$("#volumeInput").attr("value", volume);
			};

			function playSound(soundPath) {
				stopSound();
				
				var request = new XMLHttpRequest(); // Using low-level ajax api as jQuery doesn't support "arraybuffer" data type
				request.open('GET', soundPath, true);
				request.responseType = 'arraybuffer';
				request.onload = function() {
					console.log(request.response);
					audioContext.decodeAudioData(request.response, function(buffer) {
						src = audioContext.createBufferSource();
						src.buffer = buffer;
						src.loop = true;
						src.connect(analyser);
						analyser.connect(gainNode);
						gainNode.connect(audioContext.destination);

						stopSound();

						renderVuMeter(src);
						src.noteOn(0.2);
					}, function(e) {
						console.log(e);
					});
				};
				request.send();
			};
			
			function renderVuMeter(src) {(function callback(timeStamp) {
					var byteData = new Uint8Array(analyser.frequencyBinCount);
					analyser.getByteFrequencyData(byteData);
					max = -Infinity;
					for( i = 0; i < byteData.length; i++) {
						if(byteData[i] > max) {
							max = byteData[i];
						}
					}

					if(max == 0) {
						max = 1;
					}
					max = max / 255;
					max *= max;

					AvifaunaDisplay.updateVUMeter(max);
					reqAnimFrame = window.webkitRequestAnimationFrame(callback, src);
				})();
			};

			function stopSound() {
				try {
					src.noteOff(0);
					window.webkitCancelRequestAnimationFrame(reqAnimFrame);
				} catch (e) {
					//Apparently, no sound was actually being played, that's totally OK
				}
			};

			function toggleVolume() {
				volume = $("#volumeInput").attr("value");
				if(volume > 0) {
					AvifaunaConfig.defaultVolume = volume;
					changeVolume(0);
				} else {
					changeVolume(AvifaunaConfig.defaultVolume);
				}
			};
			
			return {
				init : init,
				changeVolume : changeVolume,
				playSound : playSound,
				stopSound : stopSound,
				toggleVolume : toggleVolume
			}
		})();

		exports.AvifaunaSound = AvifaunaSound;

	});
})(window);
